#!/bin/sh
#
# $FreeBSD$
#

# PROVIDE: ix-activedirectory
# REQUIRE: ix-pre-samba ix-kinit
# BEFORE: samba_server

. /etc/rc.freenas

: ${NSS_LDAP_CONF:="/usr/local/etc/nss_ldap.conf"}
: ${LDAP_CONF:="/usr/local/etc/openldap/ldap.conf"}

get_basename()
{
	local domainname="${1}" 

	base=$(echo "${domainname}" | awk '{
		n = split($0, parts, ".");
		if (n > 0) {
			base = sprintf("dc=%s", parts[1]);
			for (i=2;i <= n;i++) {
				base = sprintf("%s,dc=%s", base, parts[i]);
			}
			printf("%s", base);
		}
	}')

	echo "${base}"
}

generate_ldap_conf()
{
	LD_LIBRARY_PATH=/usr/local/lib /usr/local/bin/midclt call etc.generate ldap > /dev/null
}

generate_nss_ldap_conf()
{
	local nssconf="${NSS_LDAP_CONF}"
	local secret="${NSS_LDAP_SECRET}"
	local dcname="$(AD_get ad_dcname)"
	local domainname="$(AD_get ad_domainname)"
	local bindname="$(AD_get ad_bindname)"
	local bindpw="$(AD_get ad_bindpw)"
	local base="$(get_basename "${domainname}")"

	[ -z "${dcname}" -o -z "${base}" ] && return 1 

	cat <<-EOF > "${nssconf}"
	host ${dcname}
	base ${base}
	uri ldap://${dcname}/
	rootbinddn ${bindname}@${domainname}
	scope sub
	ssl no
	ldap_version 3
	timelimit 30
	bind_timelimit 30
	bind_policy soft
	pam_ldap_attribute uid
	nss_base_passwd ${base}?sub
	nss_base_shadow ${base}?sub
	nss_base_group ${base}?sub? &(objectCategory=group)(gidnumber=*)
	nss_map_objectclass posixAccount user
	nss_map_objectclass shadowAccount user
	nss_map_objectclass posixGroup group
	nss_map_attribute gecos cn
	nss_map_attribute homeDirectory unixHomeDirectory
	nss_map_attribute uniqueMember member
	pam_filter objectClass=user
	pam_member_attribute member
	pam_password ad

EOF
	printf "${bindpw}" > "${secret}"
	chmod 600 "${secret}"

	ln -sf ${nssconf} "$(dirname ${nssconf})/ldap.conf" 2>/dev/null
	ln -sf ${secret} "$(dirname ${secret})/ldap.secret"

	return 0
}


get_trusted()
{
	${FREENAS_SQLITE_CMD} ${RO_FREENAS_CONFIG} "
	SELECT
		ad_allow_trusted_doms

	FROM
		directoryservice_activedirectory

	ORDER BY
		-directoryservice_activedirectory.id

	LIMIT 1;
	"
}

get_cifs_homedir()
{
	${FREENAS_SQLITE_CMD} ${RO_FREENAS_CONFIG} "
	SELECT
		cifs_path

	FROM
		sharing_cifs_share

	WHERE
		cifs_home = 1

	ORDER BY
		-sharing_cifs_share.id

	LIMIT 1;
	"
}

has_unix_extensions()
{
	local ad_unix=$(${FREENAS_SQLITE_CMD} ${RO_FREENAS_CONFIG} "
	SELECT
		ad_unix_extensions

	FROM
		directoryservice_activedirectory

	ORDER BY
		-id

	LIMIT 1;
	")

	if [ "${ad_unix}" = "1" ]
	then
		return 0
	fi

	return 1
}


setup_homedirs()
{
	local trusted=$(get_trusted)
	local cifs_home="$(get_cifs_homedir)"

	if [ -n "${cifs_home}" ]
	then
		ln -sfh "$cifs_home" "/home"

		if [ "${trusted}" = "1" ]
		then
			local partitions="$(AD_query_partitions)"
			for p in ${partitions}
			do
				mkdir -p "/home/${p}"
			done

		else
			local workgroup=$(${FREENAS_SQLITE_CMD} ${RO_FREENAS_CONFIG} "SELECT cifs_srv_netbiosalias FROM services_cifs ORDER BY -id LIMIT 1")
			if [ "${workgroup}" = "" ]; then
				workgroup=$(${FREENAS_SQLITE_CMD} ${RO_FREENAS_CONFIG} "SELECT cifs_srv_netbiosname FROM services_cifs ORDER BY -id LIMIT 1")
			fi
			local homedir="/home/${workgroup}"

			mkdir -p "${homedir}"
			/usr/local/bin/winacl -a reset -p "${homedir}"
		fi

	elif [ ! -d "/home" ]
	then
		mkdir /home
	fi
}

activedirectory_start()
{
	if dirsrv_enabled activedirectory
	then
		RO_FREENAS_CONFIG=$(ro_sqlite ${name} 2> /tmp/${name}.fail && rm /tmp/${name}.fail)
		trap 'rm -f ${RO_FREENAS_CONFIG}' EXIT
		AD_init

		generate_ldap_conf

		AD_log "activedirectory_start: checking if we are joined already"
		if ! AD_testjoin_domain
		then
			AD_log "activedirectory_start: trying to join domain"
			if ! AD_join_domain
			then
				/etc/directoryservice/ActiveDirectory/ctl stop
				touch /tmp/.adalert
				return 1
			else
				if [ -f /tmp/.adalert ]
				then
					rm /tmp/.adalert
				fi
			fi
		else
			AD_log "activedirectory_start: skipping join, already joined"
			if [ -f /tmp/.adalert ]
			then
				rm /tmp/.adalert
			fi
		fi

		setup_homedirs
		create_cache_filesystem
		mkdir -p ${FREENAS_CACHEDIR}/.samba
	fi
	
	return 0
}

activedirectory_status()
{
	local res=1

	if dirsrv_enabled activedirectory
	then
		AD_init

		AD_log "activedirectory_status: checking status"
		AD_status_domain >/dev/null
		res=$?
	fi

	return ${res}
}

activedirectory_stop()
{
	AD_init

        /usr/local/www/freenasUI/tools/cachetool.py expire

	AD_log "activedirectory_stop: leaving domain"
}


name="ix-activedirectory"
start_cmd='activedirectory_start'
status_cmd='activedirectory_status'
stop_cmd='activedirectory_stop'
            
load_rc_config $name
run_rc_command "$1"
